package juc.c_018;/*
   Talk is cheap. Show me the code.
 */

import org.springframework.util.StopWatch;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

/**
 * @Description
 * @Date 2021/6/7
 * @Author liudl
 */
public class T02_AtomicVsSyncVsLongAdder {
    private static AtomicLong count1 = new AtomicLong(0);
    private static int NUMBER = 100000;
    private static long count2 = 0;
    private static LongAdder count3 = new LongAdder();

    public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch();
        Thread[] threads = new Thread[1000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int i1 = 0; i1 < NUMBER; i1++) {
                    count1.incrementAndGet();
                }
            });
        }
        runThreads(threads, "Atomic", stopWatch);
        //2 sync
        Object lock = new Object();
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int i1 = 0; i1 < NUMBER; i1++) {
                    synchronized (lock) {
                        count2++;
                    }
                }
            });
        }
        runThreads(threads, "Sync", stopWatch);
        //3 LongAdder
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int i1 = 0; i1 < NUMBER; i1++) {
                    count3.increment();
                }
            });
        }
        runThreads(threads, "LongAdder", stopWatch);
        System.out.println(stopWatch.getTotalTimeSeconds());
        System.out.println(stopWatch.prettyPrint());
    }

    private static void runThreads(Thread[] threads,String taskName,StopWatch stopWatch) {
        stopWatch.start(taskName);
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        stopWatch.stop();
    }
}
